/**
 * 
 */
package com.sfeir.client.activity;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
import com.google.web.bindery.event.shared.EventBus;
import com.sfeir.canvas.activities.client.AbstractCanvasActivity;
import com.sfeir.canvas.activities.client.event.PageChangeEvent;
import com.sfeir.canvas.util.client.ResourceManager;
import com.sfeir.client.i18n.TetrisConstants;
import com.sfeir.client.util.Constants;

/**
 * @author François LAROCHE
 * 
 */
public class MainGameActivity extends AbstractCanvasActivity {

	private static final int LOGO_BUTTON_X = 190;
	private static final int LOGO_BUTTON_Y = 100;

	private static final int PLAY_BUTTON_X = 200;
	private static final int PLAY_BUTTON_Y = 230;

	private static final int HOWTO_BUTTON_X = PLAY_BUTTON_X;
	private static final int HOWTO_BUTTON_Y = 310;

	private static final int ABOUT_BUTTON_X = PLAY_BUTTON_X;
	private static final int ABOUT_BUTTON_Y = 390;

	private static final int SETTING_BUTTON_X = PLAY_BUTTON_X;
	private static final int SETTING_BUTTON_Y = 470;

	private static final int BUTTON_WIDTH = 48;
	private static final int BUTTON_HEIGHT = 48;

	private static final int BACK_BUTTON_X = 15;
	private static final int BACK_BUTTON_Y = Constants.CANVAS_HEIGHT - 80;

	public static final String PLAY = PageChangeEvent.NEXT;

	public static final String HOWTO = "howto";
	public static final String ABOUT = "about";
	public static final String SETTINGS = "settings";

	private TetrisConstants constants = GWT.create(TetrisConstants.class);
	private EventBus bus;
	private Context2d ctx;
	private String selection = null;
	private final Image background;
	private final Image playImage;
	private final Image panelImage;
	private final Image howToImage;
	private final Image aboutImage;
	private final Image tetrisLogo;
	private final Image back;
	private final Image selectionImage;
	private final Image settingsImage;

	/**
	 * @param view
	 */
	public MainGameActivity(ResourceManager manager) {
		this.background = manager.getImage(Constants.KEY_IMAGE_BACKGROUND);
		this.panelImage = manager.getImage(Constants.KEY_IMAGE_PANEL);
		this.playImage = manager.getImage(Constants.KEY_IMAGE_PLAY);
		this.aboutImage = manager.getImage(Constants.KEY_IMAGE_ABOUT);
		this.howToImage = manager.getImage(Constants.KEY_IMAGE_HOW_TO);
		this.tetrisLogo = manager.getImage(Constants.KEY_IMAGE_TETRIS_LOGO);
		this.back = manager.getImage(Constants.KEY_IMAGE_BACK);
		this.selectionImage = manager.getImage(Constants.KEY_IMAGE_SELECTION);
		this.settingsImage = manager.getImage(Constants.KEY_IMAGE_SETTINGS);
	}

	@Override
	public void start(Canvas canvas, EventBus bus) {
		this.ctx = canvas.getContext2d();
		this.bus = bus;
		paint();
	}

	private void paint() {
		drawBackGroundImage();
		drawPlayLink();
		drawHowToLink();
		drawAboutUsLink();
		drawSettingsLink();
		drawTetrisLogo();
		drawBackImage();
		// TODO Possibility to add the option Buttons
	}

	/**
	 * Method drawing the screen logo
	 */
	private void drawTetrisLogo() {
		this.ctx.drawImage(ImageElement.as(tetrisLogo.getElement()), LOGO_BUTTON_X, LOGO_BUTTON_Y);
	}

	/**
	 * Method allowing to draw the background image
	 */
	private void drawBackGroundImage() {
		this.ctx.drawImage(ImageElement.as(this.background.getElement()), 0, 0);
		this.ctx.drawImage(ImageElement.as(this.panelImage.getElement()), 0, 0);
	}

	/**
	 * Method allowing to draw a play link on the Main Game Panel
	 */
	private void drawPlayLink() {
		this.ctx.setFillStyle("black");
		this.ctx.setFont("26px calibri bold");
		this.ctx.fillText(constants.play(), PLAY_BUTTON_X + 55, PLAY_BUTTON_Y + 30);
		this.ctx.drawImage(ImageElement.as(playImage.getElement()), PLAY_BUTTON_X, PLAY_BUTTON_Y);
	}

	/**
	 * Method allowing to draw a how to link on the Main Game Panel
	 */
	private void drawHowToLink() {
		this.ctx.setFillStyle("black");
		this.ctx.setFont("26px calibri bold");
		this.ctx.fillText(constants.howTo(), HOWTO_BUTTON_X + 55, HOWTO_BUTTON_Y + 30);
		this.ctx.drawImage(ImageElement.as(howToImage.getElement()), HOWTO_BUTTON_X, HOWTO_BUTTON_Y);
	}

	/**
	 * Method allowing to draw a about us link on the Main Game Panel
	 */
	private void drawAboutUsLink() {
		this.ctx.setFillStyle("black");
		this.ctx.setFont("26px calibri bold");
		this.ctx.fillText(constants.credits(), ABOUT_BUTTON_X + 55, ABOUT_BUTTON_Y + 30);
		this.ctx.drawImage(ImageElement.as(aboutImage.getElement()), ABOUT_BUTTON_X, ABOUT_BUTTON_Y);
	}

	/**
	 * Method allowing to draw a setting link on the Main Game Panel
	 */
	private void drawSettingsLink() {
		this.ctx.setFillStyle("black");
		this.ctx.setFont("26px calibri bold");
		this.ctx.fillText(constants.settings(), SETTING_BUTTON_X + 55, SETTING_BUTTON_Y + 30);
		this.ctx.drawImage(ImageElement.as(settingsImage.getElement()), SETTING_BUTTON_X, SETTING_BUTTON_Y);
	}

	/**
	 * Draw a back image
	 */
	private void drawBackImage() {
		this.ctx.drawImage(ImageElement.as(this.back.getElement()), BACK_BUTTON_X, BACK_BUTTON_Y);
	}

	/**
	 * Method allowing to check if the mouse hover over the play button space,
	 * in that case it will display a stroke rectangle around the play space
	 * 
	 * @param y
	 * @param x
	 */
	private void checkPlaySelection(int x, int y, int buttonX, int buttonY, String section) {
		if (((x >= buttonX) && (x <= buttonX + 400)) && ((y >= buttonY) && (y <= buttonY + BUTTON_HEIGHT))) {

			if (!section.equals(selection)) {
				displaySelectionImage(buttonX, buttonY);
				selection = section;
			}

		} else {
			if (section.equals(selection)) {
				selection = null;
				paint();
			}
		}

	}

	/**
	 * Method allowing to display a selection image on the side of the hovered
	 * section
	 * 
	 * @param x
	 * @param y
	 */
	private void displaySelectionImage(int x, int y) {
		this.ctx.drawImage(ImageElement.as(selectionImage.getElement()), x - 70, y - 7);
	}

	@Override
	public void onClick(ClickEvent event) {
		if (selection != null) {
			this.bus.fireEvent(new PageChangeEvent(selection, null));
		} else {
			int x = event.getX();
			int y = event.getY();
			// Click on the back button
			if (x >= BACK_BUTTON_X && x <= BACK_BUTTON_X + BUTTON_WIDTH && y >= BACK_BUTTON_Y
					&& y <= BACK_BUTTON_Y + BUTTON_HEIGHT) {
				// Make a redirection to the index.html
				Window.Location.replace("/");
			}
		}
	}

	@Override
	public void onMouseMove(MouseMoveEvent event) {
		checkPlaySelection(event.getX(), event.getY(), PLAY_BUTTON_X, PLAY_BUTTON_Y, PLAY);
		checkPlaySelection(event.getX(), event.getY(), HOWTO_BUTTON_X, HOWTO_BUTTON_Y, HOWTO);
		checkPlaySelection(event.getX(), event.getY(), ABOUT_BUTTON_X, ABOUT_BUTTON_Y, ABOUT);
		checkPlaySelection(event.getX(), event.getY(), SETTING_BUTTON_X, SETTING_BUTTON_Y, SETTINGS);
	}

}
